/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */
#include "Boids.h"

namespace PQClient
{
	Boids::Boids(PQEngine::SceneObject* sceneObject,Ogre::String boidsName,Ogre::String meshName)
		: NUM_FISH(20), NUM_FISH_WAYPOINTS(10), FISH_PATH_LENGTH(200),
		_sceneObject(sceneObject),_boidsName(boidsName),_meshName(meshName)
	{
		createBoidsMeshes();
		

	}

	Boids::~Boids()
	{
	}

	void Boids::update(float deltaT)
	{
		// update the fish spline path animations and loop as needed
		_animTime += deltaT;
		while (_animTime >= FISH_PATH_LENGTH){
			_animTime -= FISH_PATH_LENGTH;
		}

        for (unsigned int i = 0; i < NUM_FISH; i++){
			if(_boids[i]){
				_boids[i]->update(deltaT);

			}
			

			MeshObject* obj=_boids[i]->getMeshObject();
			// set the new position based on the spline path and set the direction based on displacement
			Ogre::Vector3 lastPos = obj->getPosition();
			obj->setPosition(_pathSplines[i].interpolate(_animTime / FISH_PATH_LENGTH));

			//_fishNodes[i]->getPosition() - lastPos, Ogre::Node::TS_PARENT, Ogre::Vector3::NEGATIVE_UNIT_X
			keepOnGround(i);
			
			obj->setDirection(obj->getPosition() - lastPos,Ogre::Node::TS_PARENT,Ogre::Vector3::NEGATIVE_UNIT_X);
			//obj->setDirection(obj->getPosition() - lastPos, Ogre::Node::TS_PARENT, Ogre::Vector3::NEGATIVE_UNIT_X);
			

			
        }

	}

	void Boids::keepOnGround(int i)
	{
		MeshObject* obj=_boids[i]->getMeshObject();
		
		_rayQuery->setRay(Ogre::Ray(obj->getPosition()+Ogre::Vector3(0,-2000,0),Ogre::Vector3::UNIT_Y));
		
		Ogre::RaySceneQueryResult &result=_rayQuery->execute();
		Ogre::RaySceneQueryResult::iterator it=result.begin();
		if(it!=result.end()&&it->worldFragment){
			obj->setPosition(obj->getPosition().x,it->worldFragment->singleIntersection.y+10,obj->getPosition().z);
		}

	}

	void Boids::createBoidsMeshes()
	{
		_rayQuery=_sceneObject->createRayQuery(Ogre::Ray());

		_pathSplines.resize(NUM_FISH);

		for (unsigned int i = 0; i < NUM_FISH; i++){
			Boid* boid=new Boid(_sceneObject,_boidsName,_meshName);
			MeshObject* meshObj=boid->getMeshObject();
			

			meshObj->getMeshComponent()->setAnim("swim");
			meshObj->getMeshComponent()->enableAnim(true);

			meshObj->setFixedYawAxis(true);


			_boids.push_back(boid);

			//path calc
			_pathSplines[i].setAutoCalculate(false);

			for (unsigned int j = 0; j < NUM_FISH_WAYPOINTS; j++){
				Ogre::Vector3 pos(Ogre::Math::SymmetricRandom() * 400, 40, Ogre::Math::SymmetricRandom() * 200);
				pos+=Ogre::Vector3(600,0,600);

				if (j > 0) {
					const Ogre::Vector3& lastPos = _pathSplines[i].getPoint(j - 1);
					Ogre::Vector3 delta = pos - lastPos;
					if (delta.length() > 750) pos = lastPos + delta.normalisedCopy() * 750;
				}
				_pathSplines[i].addPoint(pos);
			}

			// close the spline and calculate all the tangents at once
			_pathSplines[i].addPoint(_pathSplines[i].getPoint(0));
			_pathSplines[i].recalcTangents();
		}

		_animTime = 0;
	}

}
